]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
workspaceThumbnail: Track later hiding drop placeholder
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 31 Oct 2025 03:48:21 +0000 (04:48 +0100)
committerFlorian Müllner <fmuellner@gnome.org>
Mon, 24 Nov 2025 13:42:59 +0000 (14:42 +0100)
When closing the shell during a relayout we are getting this error:

    (gnome-shell:2559407): Gjs-CRITICAL **: 06:57:21.765: Object St.Bin,
    has been already disposed — impossible to access it.
    This might be caused by the object having been destroyed from C code
    using something such as destroy(), dispose(), or remove() vfuncs.
    == Stack trace for context 0x60991609b710 ==
    #0 b   resource:///org/gnome/shell/ui/workspaceThumbnail.js:1334 (5e050636fb0 @ 17)
    #1 i   resource:///org/gnome/shell/ui/main.js:279 (30c932d102e0 @ 119)

This is because the later we added is running even when not needed (e.g
when the placeholder is not visible already), but also because we may
run the later callback after the parent has been destroyed.

Prevent this to happen, by tracking the later

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3943>
(cherry picked from commit 60a071052a0e547e813c6da6db8b4fc8d3149398)

js/ui/workspaceThumbnail.js

index 34feaa1afe17ed830750523f9791759470565507..1ccabd5e76bf29509633af5c4e6ca9b55e00bf95 100644 (file)
@@ -688,6 +688,7 @@ export const ThumbnailsBox = GObject.registerClass({
     _onDestroy() {
         this._destroyThumbnails();
         this._unqueueUpdateStates();
+        this._clearDropPlaceholderLater();
 
         if (this._settings)
             this._settings.run_dispose();
@@ -769,6 +770,14 @@ export const ThumbnailsBox = GObject.registerClass({
         this.queue_relayout();
     }
 
+    _clearDropPlaceholderLater() {
+        if (!this._dropPlaceholderLater)
+            return;
+
+        global.compositor.get_laters().remove(this._dropPlaceholderLater);
+        delete this._dropPlaceholderLater;
+    }
+
     _getPlaceholderTarget(index, spacing, rtl) {
         const workspace = this._thumbnails[index];
 
@@ -1329,10 +1338,15 @@ export const ThumbnailsBox = GObject.registerClass({
             this._dropPlaceholder.allocate_preferred_size(
                 ...this._dropPlaceholder.get_position());
 
-            const laters = global.compositor.get_laters();
-            laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
-                this._dropPlaceholder.hide();
-            });
+            this._clearDropPlaceholderLater();
+            if (this._dropPlaceholder.visible) {
+                const laters = global.compositor.get_laters();
+                this._dropPlaceholderLater = laters.add(
+                    Meta.LaterType.BEFORE_REDRAW, () => {
+                        this._dropPlaceholder.hide();
+                        delete this._dropPlaceholderLater;
+                    });
+            }
         }
 
         let childBox = new Clutter.ActorBox();
@@ -1360,10 +1374,15 @@ export const ThumbnailsBox = GObject.registerClass({
 
                 this._dropPlaceholder.allocate(childBox);
 
-                const laters = global.compositor.get_laters();
-                laters.add(Meta.LaterType.BEFORE_REDRAW, () => {
-                    this._dropPlaceholder.show();
-                });
+                this._clearDropPlaceholderLater();
+                if (!this._dropPlaceholder.visible) {
+                    const laters = global.compositor.get_laters();
+                    this._dropPlaceholderLater = laters.add(
+                        Meta.LaterType.BEFORE_REDRAW, () => {
+                            this._dropPlaceholder.show();
+                            delete this._dropPlaceholderLater;
+                        });
+                }
                 x += placeholderWidth + spacing;
             }